﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.IO;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using SimpleMessaging;

public class FTFSmartCarMessages
{
    public class MessageCodes
    {
        //Define Message Types here
        public const byte MSG_POST_SYSTEM_STATE                 = 0x10;
        public const byte MSG_SET_STEERING_SERVO                = 0x11;
        public const byte MSG_SET_DRIVE_SERVO                   = 0x12;
        public const byte MSG_POST_SENSOR_DATA                  = 0x13;
        public const byte MSG_SET_AUTO_NV_PARAMETERS            = 0x14;
        public const byte MSG_SIMULATE_BUTTON_PRESS             = 0x15;
        public const byte MSG_POST_AUTO_NV_STATE_VARIABLES      = 0x16;
    }

    public class SystemStates
    {
        public const byte SYSTEM_STATE_INIT                       = 0x00;
        public const byte SYSTEM_STATE_IDLE	                      = 0x01;
        public const byte SYSTEM_STATE_AUTO_NV			          = 0x02;
    }

    public class AutoNVStates
    {
       public const byte AUTO_NV_IDLE        = 0x00;
       public const byte AUTO_NV_GO          = 0x01;
       public const byte AUTO_NV_START_DELAY = 0x02;
       public const byte AUTO_NV_STOP_DELAY  = 0x03;
    }

    public class PostSystemState : SimpleMessage
    {
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct MessageStructure
        {
            public byte MsgCode;
            public byte CurrentSystemState;
        }

        public MessageStructure MsgStruct;

        public PostSystemState()
        {
            MsgStruct = new MessageStructure();
            this.MsgStruct.MsgCode = FTFSmartCarMessages.MessageCodes.MSG_POST_SYSTEM_STATE;
        }

        public PostSystemState(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }

        protected override byte[] AssemblePayload()
        {
            return StructMap.StructToBytes(MsgStruct);
        }

        public override void FromByteArray(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }
    }

    public class SetSteeringServo : SimpleMessage
    {
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct MessageStructure
        {
            public byte MsgCode;
            public ushort SteeringServoNeutral;
            public short SteeringServoVal;
        }

        public MessageStructure MsgStruct;

        public SetSteeringServo()
        {
            MsgStruct = new MessageStructure();
            this.MsgStruct.MsgCode = FTFSmartCarMessages.MessageCodes.MSG_SET_STEERING_SERVO;
        }

        public SetSteeringServo(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }

        protected override byte[] AssemblePayload()
        {
            return StructMap.StructToBytes(MsgStruct);
        }

        public override void FromByteArray(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }
    }

    public class SetDriveServo : SimpleMessage
    {
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct MessageStructure
        {
            public byte MsgCode;
            public ushort DrivingServoNeutral;
            public short DrivingServoVal;
        }

        public MessageStructure MsgStruct;

        public SetDriveServo()
        {
            MsgStruct = new MessageStructure();
            this.MsgStruct.MsgCode = FTFSmartCarMessages.MessageCodes.MSG_SET_DRIVE_SERVO;
        }

        public SetDriveServo(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }

        protected override byte[] AssemblePayload()
        {
            return StructMap.StructToBytes(MsgStruct);
        }

        public override void FromByteArray(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }
    }

    public class PostSensorData : SimpleMessage
    {
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct MessageStructure
        {
            public byte MsgCode;
            public unsafe fixed byte IR[16];
            public unsafe fixed byte Accel[3];
            public byte Batt;
            public uint RPM;
            public byte Pot;
        }

        public MessageStructure MsgStruct;

        public PostSensorData()
        {
            MsgStruct = new MessageStructure();
            this.MsgStruct.MsgCode = FTFSmartCarMessages.MessageCodes.MSG_SET_DRIVE_SERVO;
        }

        public PostSensorData(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }

        protected override byte[] AssemblePayload()
        {
            return StructMap.StructToBytes(MsgStruct);
        }

        public override void FromByteArray(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }
    }

    public class SimulateButtonPress : SimpleMessage
    {
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct MessageStructure
        {
            public byte MsgCode;
            public byte ButtonPress;
        }

        public MessageStructure MsgStruct;

        public SimulateButtonPress ()
        {
            MsgStruct = new MessageStructure();
            this.MsgStruct.MsgCode = FTFSmartCarMessages.MessageCodes.MSG_SIMULATE_BUTTON_PRESS;
        }

        public SimulateButtonPress(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }

        protected override byte[] AssemblePayload()
        {
            return StructMap.StructToBytes(MsgStruct);
        }

        public override void FromByteArray(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }
    }

    public class SetAutoNVParameters : SimpleMessage
    {
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct MessageStructure
        {
            public byte MsgCode;
            public byte DisableAutoSteering;
            public byte DisableAutoSpeed;
            public short SteeringCtrlGain;
            public short SpeedCtrlGain;
            public short MaxDriveSpeed;
            public short SteeringIntegralGain;
            public short SteeringDifferentialGain;
            public byte CentroidFilterLength;
            public byte MinAllowableIRSignalStrength;
            public byte MaxAllowableSignalFloor;
            public byte IRFaultTickLimit;
        }

        public MessageStructure MsgStruct;

        public SetAutoNVParameters()
        {
            MsgStruct = new MessageStructure();
            this.MsgStruct.MsgCode = FTFSmartCarMessages.MessageCodes.MSG_SET_AUTO_NV_PARAMETERS;
        }

        public SetAutoNVParameters(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }

        protected override byte[] AssemblePayload()
        {
            return StructMap.StructToBytes(MsgStruct);
        }

        public override void FromByteArray(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }
    }

    public class PostAutoNVStateVariables : SimpleMessage
    {
        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct MessageStructure
        {
            public byte MsgCode;
            public byte AutoNVState;
            public short IRCentroid;
            public short IRCentroidFiltered;
            public short IRCentroidDerivative;
            public short CommandedSteering;
            public short CommandedDrive;
        }

        public MessageStructure MsgStruct;

        public PostAutoNVStateVariables()
        {
            MsgStruct = new MessageStructure();
            this.MsgStruct.MsgCode = FTFSmartCarMessages.MessageCodes.MSG_POST_AUTO_NV_STATE_VARIABLES;
        }

        public PostAutoNVStateVariables(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }

        protected override byte[] AssemblePayload()
        {
            return StructMap.StructToBytes(MsgStruct);
        }

        public override void FromByteArray(byte[] DataIn)
        {
            MsgStruct = StructMap.BytesToStruct<MessageStructure>(DataIn);
        }
    }
}